//
//  YSBookChapterContentModel.m
//  YSBookRead
//
//  Created by Kyson on 2018/11/6.
//  Copyright © 2018 YangShen. All rights reserved.
//

#import <CoreText/CoreText.h>
#import "YSBookChapterContentModel.h"
#import "YSReaderSetting.h"
#import "YSStorageManager.h"
#import "YSBookChapterModel.h"

NSString * const YSBookChapterContentLoadingTip = @"\t正在为您加载...";

@implementation YSBookChapterContentModel {
    NSMutableAttributedString *_attributedString;
}

+ (instancetype)bookChapterContentModelWith:(YSBookChapterModel *)bookChapterModel {
    YSBookChapterContentModel *chapterContentModel = [[YSBookChapterContentModel alloc] init];
    chapterContentModel.bookID        = bookChapterModel.bookID;
    chapterContentModel.chapterIndex  = bookChapterModel.chapterIndex;
    chapterContentModel.chapterID     = bookChapterModel.chapterID;
    chapterContentModel.prevChapterID = bookChapterModel.prevChapterID;
    chapterContentModel.nextChapterID = bookChapterModel.nextChapterID;
    chapterContentModel.chapterName   = bookChapterModel.chapterName;
    chapterContentModel.chapterURL    = bookChapterModel.chapterURL;
    chapterContentModel.haveCache     = bookChapterModel.haveCache;
    chapterContentModel.content = YSBookChapterContentLoadingTip;
    chapterContentModel.isLoad = NO;
    return chapterContentModel;
}

- (void)releaseChapter {
    _isLoad = NO;
    _content = YSBookChapterContentLoadingTip;
    _attributedString = nil;
    _pageRangeArray = nil;
}

- (void)updateContentPaging {
    NSLog(@"有内容: %@ 分页 %@ 章 %@", self.content.length == 0 ? @"NO" : @"YES" ,self.chapterID, self.chapterName);

    CGRect bounds = YSReaderFrame();
    NSMutableArray *rangeArray = [NSMutableArray array];
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self.content attributes:[[YSReaderSetting shareReaderSettings] readerAttributes]];
    CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrString);
    CGPathRef path = CGPathCreateWithRect(bounds, NULL);
    CFRange range = CFRangeMake(0, 0);
    NSUInteger rangeOffset = 0;

    do {
        CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(rangeOffset, 0), path, NULL);
        range = CTFrameGetVisibleStringRange(frame);
        [rangeArray addObject:[NSValue valueWithRange:NSMakeRange(rangeOffset, range.length)]];
        rangeOffset += range.length;

        if (frame) { CFRelease(frame); }

    } while (range.location + range.length < attrString.length);

    if (path) { CFRelease(path); }
    if (frameSetter) { CFRelease(frameSetter); }

    _pageRangeArray = rangeArray.copy;
    _pageCount = rangeArray.count;
    _attributedString = attrString;
}

- (NSRange)getRangeWith:(NSInteger)page {
    if (page < 0) {
        page = 0;
    } else if (page >= _pageCount) {
        page = _pageCount - 1;
    }

    return [_pageRangeArray[page] rangeValue];
}

- (NSAttributedString *)getStringWith:(NSInteger)page {
    NSRange range = [self getRangeWith:page];
    return [_attributedString attributedSubstringFromRange:range];
}

- (NSInteger)locationWith:(NSInteger)page {
    NSRange range = [self getRangeWith:page];
    return range.location;
}

- (NSInteger)centerLocationWith:(NSInteger)page {
    NSRange range = [self getRangeWith:page];
    return range.location + (range.location + range.length) / 2;
}

- (NSInteger)pageWith:(NSInteger)location {
    for (int i = 0; i < _pageCount; i++) {
        NSRange range = [self getRangeWith:i];
        if (location < (range.location + range.length)) {
            return i;
        }
    }
    return 0;
}

@end
